;# PernsonData und PersonData2 are
;# the main Pointers. The other adresses
;# are calculated on their base as
;# following:
;#
;# PersonData 		= PersonExists (0/1)
;# PersonData + 0x25	= MapID
;# PersonData +	0x27	= PosX
;# PersonData +	0x29	= PosY
;# PersonData +	0x3F	= CharName
;# PersonData2 		= Guild ID
;# PersonData2 + 0x4	= Full Char name (incl. Title and Div.)
;# PersonData2 + 0x76	= Guild Name	
;# 
;# For Person-Selection:
;# 	Starting with x=0 for first Person
;# 
;# PersonData:
;# 	$Offset_2 + x * 0x4
;# 
;# PersonData2:
;# 	$Offset_2 + x * 0x4


#Include Lib\ReadMemory.ahk
#Include Lib\WriteMemory.ahk
#Include Lib\ImageFunctions.ahk

;

;ok us
setAutoMapId(mapNumber) {
	base:=0x139E56C
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x814
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xC
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0xD70
	WriteMemoryShortInt(mapNumber,p3,"Atlantica")
	
}

;ok us
setAutoMapX(posx) {
	base:=0x139E56C
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x814
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xC
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0xD72
	WriteMemoryShortInt(posx,p3,"Atlantica")
	
}

;ok us
setAutoMapY(posy) {
	base:=0x139E56C
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x814
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0xD74
	
	WriteMemoryShortInt(posy,p3,"Atlantica")
	
}

;ok us
toggleAutoMove(b){
	base:=0x139E56C
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x814
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0xD6A
	
	WriteMemoryByte(b,p3,"Atlantica")
}


AutoMove(posx,posy,mapid) {
	toggleAutoMove(0)
	sleep, 5
	setAutoMapID(mapid)
	setAutoMapX(posx)
	setAutoMapY(posy)
	toggleAutoMove(1)
}

;ok us
getInCombat(){
	x:=ReadMemory(0x14224BC,"Atlantica")
	;msgbox, combatmem:%x%
	return x
}

;ok us
getMapID(){
	SetFormat,IntegerFast,hex
	base:=0x139E56C
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x814
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xC2
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	return x
}

;ok us
GetX() {
	SetFormat,IntegerFast,hex
	base:=0x139E56C
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x814
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xC4
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	Return x
}


;ok us
GetY() {
	SetFormat,IntegerFast,hex
	base:=0x139E56C
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x814
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xC6
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	Return x
}



;ok us
SetSpeed(s){
	WriteMemory(s, 0x13D3610,"Atlantica")
}

;ok us
ReadCursor() {
	Process, exist, Atlantica.exe
	static hand
	static sword
	static pickup
	if (!hand || cpid!=ErrorLevel) {
		SetFormat,IntegerFast,hex
		cursorbase:= 0x139E56C
		cursor_p := ReadMemory(cursorbase,"Atlantica")
		cursor_p += 0xB48
		cursor:=ReadMemory(cursor_p,"Atlantica")
		hand_a := cursor+0x4
		sword_a := cursor+0x10
		pickup_a := cursor+0x14
		hand := ReadMemory(hand_a,"Atlantica")
		sword := ReadMemory(sword_a,"Atlantica")
		pickup := ReadMemory(pickup_a,"Atlantica")
		SetFormat,IntegerFast,d
		hand+=0
		sword+=0
		pickup+=0
	}

 	
	NumPut(VarSetCapacity(cursorInfo, A_PtrSize + 16), cursorInfo, "Uint"), DllCall("GetCursorInfo", "Uint", &cursorInfo, "Uint" )
	hi := NumGet(cursorInfo, 8)
	xi:=Num2Bin(hi,32)
	xi:=Bin2Num(xi)
	;return xi
	;msgbox, %sword_a%
	if (xi=hand) {

		return, 0
		}
	if (xi=sword) {

		return, 1
	}
	if (xi=pickup) {

		return, 2
	}  
	return, -1
}


DebugCursor() {
	Process, exist, Atlantica.exe
 	
	NumPut(VarSetCapacity(cursorInfo, A_PtrSize + 16), cursorInfo, "Uint"), DllCall("GetCursorInfo", "Uint", &cursorInfo, "Uint" )
	hi := NumGet(cursorInfo, 8)
	xi:=Num2Bin(hi,32)
	xi:=Bin2Num(xi)
	
	tooltip, %xi%
	return xi
}

setZoom(z) { ; fora de batalha
; 40224B4
SetFormat,IntegerFast,hex
z:=FloatToHex(z)
zoombase:= 0x14224B4
zoom_p := ReadMemory(zoombase,"Atlantica")
zoom_p += 0x38
zoom_p2:=ReadMemory(zoom_p,"Atlantica")
zoom_1:= zoom_p2+0x30
zoom_2:= zoom_p2+0x0D0
zoom_3:= zoom_p2+0x0D4
zoom_4:= zoom_p2+0x0F8
;zoom_b:= zoom_p2+0xFC
WriteMemory(z,zoom_1,"Atlantica")

WriteMemory(z,zoom_2,"Atlantica")
WriteMemory(z,zoom_3,"Atlantica")
WriteMemory(z,zoom_4,"Atlantica")
;WriteMemory(z,zoom_b,"Atlantica")
SetFormat,IntegerFast,d
}


SetBattleZoom(z) {
SetFormat,IntegerFast,hex
z:=FloatToHex(z)
zoombase:= 0x14224B4
zoom_p := ReadMemory(zoombase,"Atlantica")
zoom_p += 0x2AC
zoom_p2:=ReadMemory(zoom_p,"Atlantica")
zoom_1:= zoom_p2+0x30
zoom_2:= zoom_p2+0xD0
zoom_3:= zoom_p2+0xD4
;zoom_4:= zoom_p2+0x128
;zoom_b:= zoom_p2+0xFC
WriteMemory(z,zoom_1,"Atlantica")
WriteMemory(z,zoom_2,"Atlantica")
WriteMemory(z,zoom_3,"Atlantica")
;WriteMemory(z,zoom_4,"Atlantica")
;WriteMemory(z,zoom_b,"Atlantica")
SetFormat,IntegerFast,d
}



SetCamera(d) { ; angulo horizontal
SetFormat,IntegerFast,hex
d:=FloatToHex(d)
camerabase:= 0x14224B4
camera_p := ReadMemory(camerabase,"Atlantica")
camera_p += 0x38
camera_p2:=ReadMemory(camera_p,"Atlantica")
camera:= camera_p2+0xAC
;msgbox %camera%
WriteMemory(d,camera,"Atlantica")
SetFormat,IntegerFast,d
}

FloatToHex(f) {
   form := A_FormatInteger
   SetFormat Integer, HEX
   v := DllCall("MulDiv", Float,f, Int,1, Int,1, UInt)
   SetFormat Integer, %form%
   Return v
}

decodeInteger(ptr) {
return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24
}



Num2Bin(n,bits=0) {     ; Return LS "bits" of binary representation of "n"
   IfLess bits,1, Loop  ; n < 0: leading 1's are omitted. -1 -> 1, 0 -> 0
      {
         b := n&1 b
         n := n>>1
         If (n = n>>1)
            Break
      }
   Else Loop %bits%
      {
         b := n&1 b
         n := n>>1
      }
   Return b
}


Bin2Num(bits,neg="") {  ; Return number converted from the binary "bits" string
   n = 0                ; If "neg" is not 0 or empty, 11..1 assumed on the left
   Loop Parse, bits
      n += n + A_LoopField
   Return n - !(neg<1)*(1<<StrLen(bits))
}

;ok us
getHP(char) {
    SetFormat,IntegerFast,hex
	hp:=0
    base:=0x139E56C
    ap_p1:=ReadMemory(base,"Atlantica")
    ap_p1+=0x814
    ap_p2:=ReadMemory(ap_p1,"Atlantica")
    ap_p2+=0xc
    ap_p3:=ReadMemory(ap_p2,"Atlantica")
    ap_p3+=0x30
    ap_p4:=ReadMemory(ap_p3,"Atlantica")
    ap_p4+=0x24b8
	ap_p4+=(char-1)*0x7C8
	hp:=ReadMemory(ap_p4,"Atlantica")
	SetFormat,IntegerFast,d
	hp+=0
	;sleep, 100
	return, hp
}

;ok us
getMP(char) {
    SetFormat,IntegerFast,hex
    base:=0x139E56C
    ap_p1:=ReadMemory(base,"Atlantica")
    ap_p1+=0x814
    ap_p2:=ReadMemory(ap_p1,"Atlantica")
    ap_p2+=0xc
    ap_p3:=ReadMemory(ap_p2,"Atlantica")
    ap_p3+=0x30
    ap_p4:=ReadMemory(ap_p3,"Atlantica")
    ap_p4+=0x24bc
	ap_p4+=(char-1)*0x7C8
	mp:=ReadMemory(ap_p4,"Atlantica")
	SetFormat,IntegerFast,d
	mp+=0
	return, mp
}

;ok us
getActiveChar() {
	
	SetFormat,IntegerFast,hex
	
	base:=0x139E56C
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x11498
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0x4c
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x4a8
	char:=ReadMemory(p3,"Atlantica")
	SetFormat,IntegerFast,d
	char+=1
	return char
}


getNearX(pos) {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0x10 + (4*pos)
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xAC
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	return, x
	}
	


getNearY(pos) {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0x10 + (4*pos)
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xAE
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	return, x
	}



getNome(pos) {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0x10 + (4*pos)
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xC4
	name:=ReadMemory_str(p4)
	SetFormat,IntegerFast,d
	return, name
	
	
}

getMPDeficit(){
		
		static maxmp:=Object()
		static mp:=Object()
		mpdeficittotal=0
		
		loop, 9 {
			mp[A_Index]:=getMP(A_Index)
		    if (mp[A_Index]>maxmp[A_Index]) {
				maxmp[A_Index]:=mp[A_Index]
			}	
			mpdeficittotal+=(maxmp[A_Index]-mp[A_Index])
		}
	return mpdeficittotal
	}
	
getHPDeficit() {
		
		static maxhp:=Object()
		static hp:=Object()
		hpdeficittotal=0
		
		loop, 9 {
			hp[A_Index]:=getHP(A_Index)
		    if (hp[A_Index]>maxhp[A_Index]) {
				maxhp[A_Index]:=hp[A_Index]
			}	
			hpdeficittotal+=(maxhp[A_Index]-hp[A_Index])
		}
	return hpdeficittotal
	
	
}
	
getDeadMercs() {
	static hp:=Object()
	retorno:=0
	loop, 9 {
		hp[A_Index]:=getHP(A_Index)
		if (hp[A_Index]=0) {
			retorno++
		}	
	}
	return retorno
	}

closestMob() {
	i:=1
	posd:=999
	posi:=-1
	while (i<30) {
		nome:=getNome(i)
		Loop, read, %A_WorkingDir%\moblist.txt
		{
			Loop, parse, A_LoopReadLine, %A_Tab%
			{
				If (InStr(nome, A_LoopField)){
					x:=getNearX(i)
					y:=getNearY(i)
					myX:=getX()
					myY:=getY()
					dist:=getDistanceD(x,y,myX,myY)
					if (dist<posd) {
						posd:=dist
						posi:=i
					}
					;msgbox, %i% %nome% %x% %y% %dist%
				}
		
			}
		}


		
		i++
	}
	if (posi=-1) {
		msgbox, sem mobs validos
		return
	}
	nome:=getNome(posi)
	x:=getNearX(posi)
	y:=getNearY(posi)
	tooltip , closest %nome% %x% %y% %dist%, 0, 0, 1
	AutoMove(x,y,getMapID())

	return, posi
	
}

faceMob(posi) {
	myX:=getX()
	myY:=getY()
	x:=getNearX(posi)
	y:=getNearY(posi)
	
	dist:=getDistanceD(x,y,myX,myY)
	nome:=getNome(posi)
	tooltip , facing %nome% %x% %y% %dist%, 0, 0, 1
	xdif:=x-GetX()
	ydif:=y-GetY()
	if (xdif=0 && ydif>0) {
		SetCamera(1.57)
	}
	else if (xdif=0 && ydif<0) {
		SetCamera(4.71)
	}
	else if (xdif>0 && ydif>0) {
		SetCamera(0.78)
	}
	else if (xdif<0 && ydif<0) {
		SetCamera(5.49)
	}
	else if (xdif=0 && ydif>0) {
		SetCamera(0.0)
	}
	else {
		SetCamera(3.14)
	}
	send, {w down}
	sleep, 25
	send {w up}
	

}

GetTurn() {
if (!inBattle()){
return, -1
}
SetFormat,IntegerFast,hex
;base:=0x13105E8
base:=0x139E56C

p1:=ReadMemory(base,"Atlantica")
p1+=0x8EC
p2:=ReadMemory(p1,"Atlantica")
p2+=0x8
p3:=ReadMemory(p2,"Atlantica")
p3+=0x7A50
;7A50
turn:=ReadMemory(p3,"Atlantica")
SetFormat,IntegerFast,d
turn+=0
return, turn
}
	
getDistance() {
	global autox
	global autoy
	d:=sqrt((getX()-autox)**2+(getY()-autoy)**2)
	return d
	}
	
	getDistanceD(x1, y1, x2, y2) {
	d:=sqrt((x1-x2)**2+(y1-y2)**2)
	return d 
	}
	
	
returnToSpot() {
	global maxdistance
	global autox
	global autoy
	global automapid
	distance:=getDistance()
	if (maxdistance!=-1 && distance > maxdistance) {
		automove(autox,autoy,automapid)
		while (15<distance) {
			oldX:=GetX()
			oldY:=getY()
			sleep, 2500
			x:=getX()
			y:=getY()
			d:=sqrt((x-oldX)**2+(y-oldY)**2)
			if (d<4) {
				paranoid()
				Send , {s down}
				sleep, 3000
				send , {s up}
			}
			automove(autox,autoy,automapid)
			distance:=getDistance()
			tooltip, distance:%distance%,0, 0, 1
		}
		send, w
		sleep, 300
		ImageSearch, sx, sy, 0, 0, 1000, 1000, *20 Images\Misc\sim.png
		MouseClick, left, sx, sy
	}
}

FPV(){
	SetBattleZoom(0.0)
	;SetCamera(0.0)
}

paranoid(){
	globalVars()
	global paranoid
	global automapid ; se -1 auto-run back off.
	global autox
	global autoy
	
	global automapid2
	global autox2
	global autoy2
	
	global automapid3
	global autox3
	global autoy3
	
	static ltele:=A_Now
	static cresc:=0
	
	mob:=0
	i:=1
	
	if (paranoid>0 && (getMapID()>72 || (getMapID()=0))){          
		loop {
			sentinela:=0
			mob:=0
			while (i<45) {
				nome:=getNome(i)
				;msgbox, %nome%
				;nome:="paunocussj"
				Loop, read, %A_WorkingDir%\moblist.txt
				{
					Loop, parse, A_LoopReadLine, %A_Tab%
					{
						StringLen, length, nome
						If (InStr(nome, A_LoopField)){
							mob:=1
							break
						}
						else if (length=0 || InStr(nome, "Ravock") || InStr(nome, "Zuy") || InStr(nome, "Apsalar") || InStr(nome, "Blacklycan") || InStr(nome, "Xima") || InStr(nome,"StarRock")) {
							mob:=1
							break
						}
					}
				}
				if (mob=0) {
					while (getMapId()!=1) {
						;tpToHanyang()
					}
					now:=A_Now
					EnvSub, ltele, now, minutes
					rmin:=cresc+60
					rmax:=cresc+120
					Random, r, rmin, rmax
					if (r<360) {
						cresc+=60
					}
					else {
						cresc:=0
					}
					ltele:=A_Now
					elapsed:=0
					while (elapsed<r) {
						automove(164,191,1)
						;now:=A_Now
						EnvSub, elapsed, now, seconds
						
						;x:=getNearX(i)
						;y:=getNearY(i)
						sentinela:=1
					    tooltip, ESPERANDO tempo:%elapsed%/%r% douchebag:%nome% , 0, 0, 1 
						sleep, 1000
					}
				if (automapid2>-1 && automapid3<0) {
					tmpmap:=automapid
					tmpx:=autox
					tmpy:=autoy
					
					global automapid:=automapid2
					global autox:=autox2
					global autoy:=autoy2
					
					global automapid2:=tmpmap
					global autox2:=tmpx
					global autoy2:=tmpy
					amIDead(automapid,autox,autoy)
					}
				else if (automapid2>-1 && automapid3>-1) {
					tmpmap:=automapid
					tmpx:=autox
					tmpy:=autoy
					
					global automapid:=automapid2
					global autox:=autox2
					global autoy:=autoy2
					
					global automapid2:=automapid3
					global autox2:=autox3
					global autoy2:=autoy3
					
					global automapid3:=tmpmap
					global autox3:=tmpx
					global autoy3:=tmpy
					amIDead(automapid,autox,autoy)
				}
				
				paranoid()
				}
			i++
			mob:=0
			}
		if (sentinela=0) {
			break
		}
	}
}

}

getABStatus() {
SetFormat,IntegerFast,hex
base:=0x139E56C
p1:=ReadMemory(base,"Atlantica")
p1+=0x12BB4
x:=ReadMemory(p1,"Atlantica")
SetFormat,IntegerFast,d
x+=0
return x
}



getABNumber(){
SetFormat,IntegerFast,hex
base:=0x139E56C
p1:=ReadMemory(base,"Atlantica")
p1+=0x12BB8
x:=ReadMemory(p1,"Atlantica")
SetFormat,IntegerFast,d
x+=0
return x 
}

setPID() {
	global gpid
	WinGet, gpid, PID, Atlantica Online
}